#include "ADCM_Domain.h"

using namespace log4cxx;
using namespace log4cxx::xml;
using namespace log4cxx::helpers;

ADCM_Domain::ADCM_Domain(wstring& dc, wstring& fqdn): _dc(dc), _fqdn(fqdn), _domainID(0)
{
    DOMConfigurator::configure("LogConfig.xml");
	
}

ADCM_Domain::~ADCM_Domain() 
{}

void 
ADCM_Domain::fqdnToDN(wstring & dn)
{
    const wstring _temp= getFqdn();
    dn=LDAP_COMP;
    for(int i=0; i< _temp.size(); i++)
    {
        if ('.' != _temp.at(i))
        {
            dn+=_temp.at(i);
        }
        else
        {
            dn+=L_DC;
        }
    }
}

int 
ADCM_Domain::loadComputers(const wstring& user, 
						   const wstring& pass, 
						   vector<ADCM_Computer>& computers)
{
    LoggerPtr loggerADCM(Logger::getLogger("loggerADCM"));
    HRESULT hr;
    IDirectorySearch *pDSSearch;
    wstring dn;

    // Initialize COM before calling any ADSI functions or interfaces.
    CoInitialize(NULL);
    fqdnToDN(dn);
	hr = ADsOpenObject( dn.c_str(), user.c_str(), pass.c_str(), 
                        ADS_SECURE_AUTHENTICATION,
                        IID_IDirectorySearch, 
                        (void**) &pDSSearch);
    
    if ( !SUCCEEDED(hr) )
    {
		wstringstream wout;
		wout << "Fail at domain connection : ";
		wout << hex << hr;
        LOG4CXX_ERROR(loggerADCM,wout.str());
        return 0;
    }
    
    ADS_SEARCH_COLUMN col;
    LPWSTR pszAttr[] = { L"cn", L"operatingSystem" };
    ADS_SEARCH_HANDLE hSearch;
    DWORD dwCount = 0;
    DWORD dwAttrNameSize = sizeof(pszAttr)/sizeof(LPWSTR);

    // Search for all objects with the 'cn' property that start with c.
	hr = pDSSearch->ExecuteSearch(L"(objectClass=computer)",pszAttr ,dwAttrNameSize,&hSearch );	
	
    while( pDSSearch->GetNextRow( hSearch) != S_ADS_NOMORE_ROWS )
    {
		wstring name;
		wstring so;
        // Get the property.
        hr = pDSSearch->GetColumn( hSearch, L"cn", &col );
 
		// If this object supports this attribute, display it.
        if ( SUCCEEDED(hr) )
        { 
		    if (col.dwADsType == ADSTYPE_CASE_IGNORE_STRING)
		   {
			   name= wstring(col.pADsValues->CaseIgnoreString);
		   }
           pDSSearch->FreeColumn( &col );
        }
        else
            LOG4CXX_ERROR(loggerADCM,"Common Name property NOT available");

		// Get the property.
        hr = pDSSearch->GetColumn( hSearch, L"operatingSystem", &col );
 
        // If this object supports this attribute, display it.
        if ( SUCCEEDED(hr) )
        { 
           if (col.dwADsType == ADSTYPE_CASE_IGNORE_STRING)
           {
		        so = wstring(col.pADsValues->CaseIgnoreString);
           }
           pDSSearch->FreeColumn( &col );
        }
        else
            LOG4CXX_ERROR(loggerADCM,"Operating System property NOT available");
		
		computers.push_back(ADCM_Computer(name, so));
        dwCount++;
		
    }
	
    pDSSearch->CloseSearchHandle(hSearch);
    pDSSearch->Release();

    if ( !SUCCEEDED(hr) )
    {
        LOG4CXX_ERROR(loggerADCM,"Fail at get Computer Attributes");
        return 0;
    }

    CoUninitialize();
	return 1;
}
